#include "rotary_encoder.h"
#include "board.h"
#include "FreeRTOS.h"
#include "task.h"
#include "LOG.h"
#include "pico/stdlib.h"
#include "hardware/gpio.h"

// 按键配置
#define ROTARY_BUTTON_LONG_PRESS_TIME_MS 1000

// 旋转编码器状态
static uint8_t last_rotary_state = 0;  // 上一次编码器状态
static volatile int16_t rotary_counter = 0;     // 旋转计数器（使用volatile确保中断安全）

// 旋转速度检测相关变量
static int16_t rotation_count_in_interval = 0;  // 测量间隔内的旋转次数
static uint32_t last_speed_measurement_time = 0; // 上次速度测量时间
static rotary_speed_t current_rotation_speed = ROTARY_SPEED_STOP; // 当前旋转速度

// 按钮状态
static uint32_t button_press_start_time = 0;     // 按钮按下开始时间
static bool button_last_raw_state = true;        // 按钮上一次的原始状态（上拉时未按下为高电平）
static bool button_is_pressed = false;           // 按钮当前是否处于按下状态

// 旋转编码器初始化
void rotary_encoder_init(void) {
    // 初始化旋转编码器GPIO为输入模式
    gpio_init(KEY_A_PIN);
    gpio_set_dir(KEY_A_PIN, GPIO_IN);
    gpio_pull_up(KEY_A_PIN); // 启用上拉电阻
    
    gpio_init(KEY_B_PIN);
    gpio_set_dir(KEY_B_PIN, GPIO_IN);
    gpio_pull_up(KEY_B_PIN); // 启用上拉电阻
    
    gpio_init(KEY_T_PIN);
    gpio_set_dir(KEY_T_PIN, GPIO_IN);
    gpio_pull_up(KEY_T_PIN); // 启用上拉电阻
    
    // 初始化状态
    last_rotary_state = (gpio_get(KEY_A_PIN) << 1) | gpio_get(KEY_B_PIN);
    rotary_counter = 0;
    rotation_count_in_interval = 0;
    last_speed_measurement_time = xTaskGetTickCount();
    current_rotation_speed = ROTARY_SPEED_STOP;
    
    button_last_raw_state = gpio_get(KEY_T_PIN); // 初始化按钮状态
    button_is_pressed = false;
    button_press_start_time = 0;

    LOG_INFO("Rotary encoder initialized: A=%d, B=%d, T=%d", KEY_A_PIN, KEY_B_PIN, KEY_T_PIN);
}

// 检测旋转编码器旋转方向
// 返回值: 0=无动作, 1=顺时针, 2=逆时针
static char encoder_scan(void) {
    static uint8_t last_a_state = 0;    // A相上一次的状态
    static uint8_t last_b_state = 0;    // B相上一次的状态
    char scan_result = 0;
    
    uint8_t current_a_state = gpio_get(KEY_A_PIN);
    uint8_t current_b_state = gpio_get(KEY_B_PIN);
    
    // 当A相发生跳变时采集B相当前的状态，并将B相与上一次的状态进行对比
    if (current_a_state != last_a_state) {
        // 若A 0->1 时，B 1->0 顺时针；若A 1->0 时，B 0->1 顺时针；
        // 若A 0->1 时，B 0->1 逆时针；若A 1->0 时，B 1->0 逆时针
        
        if (current_a_state == 1) {     // A相从0变为1（上升沿）
            // B相从1变为0
            if ((last_b_state == 1) && (current_b_state == 0)) {
                scan_result = 1;  // 顺时针
            }
            // B相从0变为1
            if ((last_b_state == 0) && (current_b_state == 1)) {
                scan_result = 2; // 逆时针
            }
            
            // 特殊情况处理：A上升沿时，B相状态不变
            // B相保持为0
            if ((last_b_state == current_b_state) && (current_b_state == 0)) {
                scan_result = 1;  // 顺时针
            }
            // B相保持为1
            if ((last_b_state == current_b_state) && (current_b_state == 1)) {
                scan_result = 2;  // 逆时针
            }
        } else {  // A相从1变为0（下降沿）
            // B相从1变为0
            if ((last_b_state == 1) && (current_b_state == 0)) {
                scan_result = 2;  // 逆时针
            }
            // B相从0变为1
            if ((last_b_state == 0) && (current_b_state == 1)) {
                scan_result = 1;  // 顺时针
            }
            
            // 特殊情况处理：A下降沿时，B相状态不变
            // B相保持为0
            if ((last_b_state == current_b_state) && (current_b_state == 0)) {
                scan_result = 2;  // 逆时针
            }
            // B相保持为1
            if ((last_b_state == current_b_state) && (current_b_state == 1)) {
                scan_result = 1;  // 顺时针
            }
        }
        
        last_a_state = current_a_state;   // 更新A相上一次状态
        last_b_state = current_b_state;   // 更新B相上一次状态
        return scan_result;               // 返回值: 0=无动作, 1=顺时针, 2=逆时针
    }
    
    return 0;
}

static uint16_t rotary_time_count = 0;

// 处理旋转编码器
rotary_event_t rotary_encoder_process(void) {
    rotary_event_t rotation_event = ROTARY_EVENT_NONE;

    // 检测按钮状态
    uint8_t raw_button_state = gpio_get(KEY_T_PIN);
    // 检测旋转编码器旋转
    uint8_t rotation = encoder_scan();

    if (rotation == 1) {
        // 顺时针旋转
        rotary_counter++;
        LOG_DEBUG("Rotary encoder clockwise, counter: %d", rotary_counter);
        if (rotary_counter %2)
        {
            rotation_event = ROTARY_EVENT_CLOCKWISE;
        }
    } else if (rotation == 2) {
        // 逆时针旋转
        rotary_counter--;
        LOG_DEBUG("Rotary encoder counter-clockwise, counter: %d", rotary_counter);
        if (rotary_counter %2)
        {
            rotation_event = ROTARY_EVENT_COUNTERCLOCKWISE;
        }
    }

    if (raw_button_state == 0)
    {
        // 按钮被按下（低电平）
        button_is_pressed = true;
        rotary_time_count += MAIN_TASK_DELAY_MS;

        // 只有当按压时间达到长按阈值时才触发
        if (rotary_time_count >= ROTARY_BUTTON_LONG_PRESS_TIME_MS)
        {
            // 长按事件（只触发一次）
            LOG_DEBUG("Rotary button long pressed event (continuous check), time count: %d ms", rotary_time_count);
            // 触发长按事件后，将button_is_pressed设为false以避免重复触发
            button_is_pressed = false;
            rotary_time_count = 0;
            rotation_event =  ROTARY_EVENT_BUTTON_LONG_PRESSED;
        }
    }
    else if (button_last_raw_state == 0)
    {
        button_is_pressed = false;
        // 短按事件
        LOG_DEBUG("Rotary button pressed event");
        rotary_time_count = 0;
        rotation_event = ROTARY_EVENT_BUTTON_PRESSED;
    }

    button_last_raw_state = raw_button_state;
   
    return rotation_event;
}
